package com.example.question.tree.tree2;

import com.example.question.tree.tree1.Tree;
import com.example.question.tree.tree1.TreeNode;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * @Date 2023-07-09
 * @Author Jonathan
 */
public class Code01_662 {

    public static void main(String[] args) {
        TreeNode tree = Tree.createTree(new Integer[]{1, 3, 5, 6, null, null, null, null, 2, null, 9, 2, null, 9, 7, null});
        Code01_662 code = new Code01_662();
        System.out.println(code.widthOfBinaryTree(tree));
    }


    public int widthOfBinaryTree1(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Queue<Helper> queue = new LinkedList<>();
        queue.offer(new Helper(root, 1));
        int maxWidth = 0, start = 0, end = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                Helper helper = queue.poll();
                if (i == 0) {
                    start = helper.seq;
                }
                if (i == size - 1) {
                    end = helper.seq;
                }
                if (helper.node.left != null) {
                    queue.offer(new Helper(helper.node.left, 2 * helper.seq));
                }
                if (helper.node.right != null) {
                    queue.offer(new Helper(helper.node.right, 2 * helper.seq + 1));
                }
            }
            maxWidth = Math.max(maxWidth, end - start + 1);
        }
        return maxWidth;
    }


    static class Helper {
        private TreeNode node;
        private int seq;

        public Helper(TreeNode node, int seq) {
            this.node = node;
            this.seq = seq;
        }
    }

    public int widthOfBinaryTree(TreeNode root) {
        return dfs(root, 0, 1, new ArrayList<>(), new ArrayList<>());
    }

    public int dfs(TreeNode node, int level, int seq, List<Integer> start, List<Integer> end) {
        if (node == null) {
            return 0;
        }
        if (start.size() == level) {
            start.add(seq);
            end.add(seq);
        } else {
            end.set(level, seq);
        }
        // 前序
        int left = dfs(node.left, level + 1, 2 * seq, start, end);
        int right = dfs(node.right, level + 1, 2 * seq + 1, start, end);
        // 后续 回溯
        int i = end.get(level) - start.get(level) + 1;
        return Math.max(i, Math.max(right, left));
    }

    static class Info {
        private Integer seq;
        private Integer level;
        private Integer maxWidth;

        public Info(Integer seq, Integer level, Integer maxWidth) {
            this.seq = seq;
            this.level = level;
            this.maxWidth = maxWidth;
        }
    }
}
